#include  "../../bootloader/linkage.h"

R15	=	0x00
R14	=	0x08
R13	=	0x10
R12	=	0x18
R11	=	0x20
R10	=	0x28
R9	=	0x30
R8	=	0x38
RBX	=	0x40
RCX	=	0x48
RDX	=	0x50
RSI	=	0x58
RDI	=	0x60
RBP	=	0x68
DS	=	0x70
ES	=	0x78
RAX	=	0x80
FUNC	=	0x88
ERRCODE	=	0x90
RIP	=	0x98
CS	=	0xa0
RFLAGS	=	0xa8
OLDRSP	=	0xb0
OLDSS	=	0xb8




ignore_int_restore:
	
	popq	%rax
	movq	%rax,	%ds
	popq	%rax
	movq	%rax,	%es

	popq	%r15
	popq	%r14
	popq	%r13
	popq	%r12
	popq	%r11
	popq	%r10
	popq	%r9
	popq	%r8

	popq	%rsi
	popq	%rdi
	popq	%rbp
	popq	%rdx
	popq	%rcx
	popq	%rbx
	popq	%rax

	iretq

.macro ignore_int num
.global ignore_init\num
ignore_init\num:
	cld
	pushq	%rax
	pushq	%rbx
	pushq	%rcx
	pushq	%rdx
	pushq	%rbp
	pushq	%rdi
	pushq	%rsi

	pushq	%r8
	pushq	%r9
	pushq	%r10
	pushq	%r11
	pushq	%r12
	pushq	%r13
	pushq	%r14
	pushq	%r15

	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax

	movq	$0x10,	%rax
	movq	%rax,	%ds
	movq	%rax,	%es
	movq 	%rsp, %rsi
	movq 	$\num,   %rdi
	callq	_ZN16interruptmanager17DoInterruptHandleEyP10StackFrame
	movq	%rax, %rsp
	jmp ignore_int_restore


.endm

ignore_int 0
ignore_int 1
ignore_int 2
ignore_int 3
ignore_int 4
ignore_int 5
ignore_int 6
ignore_int 7
ignore_int 8
ignore_int 9
ignore_int 10
ignore_int 11
ignore_int 12
ignore_int 13
ignore_int 14
ignore_int 15
ignore_int 16
ignore_int 17
ignore_int 18
ignore_int 19
ignore_int 20
ignore_int 21
ignore_int 22
ignore_int 23
ignore_int 24
ignore_int 25
ignore_int 26
ignore_int 27
ignore_int 28
ignore_int 29
ignore_int 30
ignore_int 31
ignore_int 32
ignore_int 33
ignore_int 34
ignore_int 35
ignore_int 36
ignore_int 37
ignore_int 38
ignore_int 39
ignore_int 40
ignore_int 41
ignore_int 42
ignore_int 43
ignore_int 44
ignore_int 45
ignore_int 46
ignore_int 47
ignore_int 48
ignore_int 49
ignore_int 50
ignore_int 51
ignore_int 52
ignore_int 53
ignore_int 54
ignore_int 55
ignore_int 56
ignore_int 57
ignore_int 58
ignore_int 59
ignore_int 60
ignore_int 61
ignore_int 62
ignore_int 63
ignore_int 64
ignore_int 65
ignore_int 66
ignore_int 67
ignore_int 68
ignore_int 69
ignore_int 70
ignore_int 71
ignore_int 72
ignore_int 73
ignore_int 74
ignore_int 75
ignore_int 76
ignore_int 77
ignore_int 78
ignore_int 79
ignore_int 80
ignore_int 81
ignore_int 82
ignore_int 83
ignore_int 84
ignore_int 85
ignore_int 86
ignore_int 87
ignore_int 88
ignore_int 89
ignore_int 90
ignore_int 91
ignore_int 92
ignore_int 93
ignore_int 94
ignore_int 95
ignore_int 96
ignore_int 97
ignore_int 98
ignore_int 99
ignore_int 100
ignore_int 101
ignore_int 102
ignore_int 103
ignore_int 104
ignore_int 105
ignore_int 106
ignore_int 107
ignore_int 108
ignore_int 109
ignore_int 110
ignore_int 111
ignore_int 112
ignore_int 113
ignore_int 114
ignore_int 115
ignore_int 116
ignore_int 117
ignore_int 118
ignore_int 119
ignore_int 120
ignore_int 121
ignore_int 122
ignore_int 123
ignore_int 124
ignore_int 125
ignore_int 126
ignore_int 127
ignore_int 128
ignore_int 129
ignore_int 130
ignore_int 131
ignore_int 132
ignore_int 133
ignore_int 134
ignore_int 135
ignore_int 136
ignore_int 137
ignore_int 138
ignore_int 139
ignore_int 140
ignore_int 141
ignore_int 142
ignore_int 143
ignore_int 144
ignore_int 145
ignore_int 146
ignore_int 147
ignore_int 148
ignore_int 149
ignore_int 150
ignore_int 151
ignore_int 152
ignore_int 153
ignore_int 154
ignore_int 155
ignore_int 156
ignore_int 157
ignore_int 158
ignore_int 159
ignore_int 160
ignore_int 161
ignore_int 162
ignore_int 163
ignore_int 164
ignore_int 165
ignore_int 166
ignore_int 167
ignore_int 168
ignore_int 169
ignore_int 170
ignore_int 171
ignore_int 172
ignore_int 173
ignore_int 174
ignore_int 175
ignore_int 176
ignore_int 177
ignore_int 178
ignore_int 179
ignore_int 180
ignore_int 181
ignore_int 182
ignore_int 183
ignore_int 184
ignore_int 185
ignore_int 186
ignore_int 187
ignore_int 188
ignore_int 189
ignore_int 190
ignore_int 191
ignore_int 192
ignore_int 193
ignore_int 194
ignore_int 195
ignore_int 196
ignore_int 197
ignore_int 198
ignore_int 199
ignore_int 200
ignore_int 201
ignore_int 202
ignore_int 203
ignore_int 204
ignore_int 205
ignore_int 206
ignore_int 207
ignore_int 208
ignore_int 209
ignore_int 210
ignore_int 211
ignore_int 212
ignore_int 213
ignore_int 214
ignore_int 215
ignore_int 216
ignore_int 217
ignore_int 218
ignore_int 219
ignore_int 220
ignore_int 221
ignore_int 222
ignore_int 223
ignore_int 224
ignore_int 225
ignore_int 226
ignore_int 227
ignore_int 228
ignore_int 229
ignore_int 230
ignore_int 231
ignore_int 232
ignore_int 233
ignore_int 234
ignore_int 235
ignore_int 236
ignore_int 237
ignore_int 238
ignore_int 239
ignore_int 240
ignore_int 241
ignore_int 242
ignore_int 243
ignore_int 244
ignore_int 245
ignore_int 246
ignore_int 247
ignore_int 248
ignore_int 249
ignore_int 250
ignore_int 251
ignore_int 252
ignore_int 253
ignore_int 254
ignore_int 255


ENTRY(ignore_init)
	cld
	pushq	%rax
	pushq	%rbx
	pushq	%rcx
	pushq	%rdx
	pushq	%rbp
	pushq	%rdi
	pushq	%rsi

	pushq	%r8
	pushq	%r9
	pushq	%r10
	pushq	%r11
	pushq	%r12
	pushq	%r13
	pushq	%r14
	pushq	%r15

	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax

	movq	$0x10,	%rax
	movq	%rax,	%ds
	movq	%rax,	%es
	movq 	%rsp, %rsi
	movq 	$0,   %rdi
	callq	_ZN16interruptmanager17DoInterruptHandleEyP10StackFrame
	movq	%rax, %rsp
	jmp ignore_int_restore



.macro HandleInterruptRequest num
.global _ZN16interruptmanager26HandleInterruptRequest\num\()Ev
_ZN16interruptmanager26HandleInterruptRequest\num\()Ev:
	cli
	pushq $0
	pushq %rax
	pushq %rax
	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax
	xorq	%rax,	%rax

	pushq	%rbp
	pushq	%rdi
	pushq	%rsi
	pushq	%rdx
	pushq	%rcx
	pushq	%rbx
	pushq	%r8
	pushq	%r9
	pushq	%r10
	pushq	%r11
	pushq	%r12
	pushq	%r13
	pushq	%r14
	pushq	%r15	

	movq	$0x10,	%rdi
	movq	%rdi,	%ds
	movq	%rdi,	%es

	

    #leaq interruptnumber(%rip), %rsi
	#movb $\num, (%rsi)
	mov $\num, %rdi
	movq %rsp, %rsi
	callq _ZN16interruptmanager17DoInterruptHandleEyP10StackFrame
	jmp ret_from_exception
.endm
	
	jz next
	xchg %bx,%bx 
next:	

HandleInterruptRequest 0x20
HandleInterruptRequest 0x21
HandleInterruptRequest 0x22
HandleInterruptRequest 0x23
HandleInterruptRequest 0x24
HandleInterruptRequest 0x25
HandleInterruptRequest 0x26
HandleInterruptRequest 0x27
HandleInterruptRequest 0x28
HandleInterruptRequest 0x29
HandleInterruptRequest 0x2A
HandleInterruptRequest 0x2B
HandleInterruptRequest 0x2C
HandleInterruptRequest 0x2D
HandleInterruptRequest 0x2E
HandleInterruptRequest 0x2F
HandleInterruptRequest 0x30
HandleInterruptRequest 0x31


HandleInterruptRequest 0xC8
HandleInterruptRequest 0xC9
HandleInterruptRequest 0xCA
HandleInterruptRequest 0xCB
HandleInterruptRequest 0xCC
HandleInterruptRequest 0xCD
HandleInterruptRequest 0xCE
HandleInterruptRequest 0xCF
HandleInterruptRequest 0xD0
HandleInterruptRequest 0xD1



RESTORE_ALL:

	popq	%r15;		
	popq	%r14;		
	popq	%r13;		
	popq	%r12;		
	popq	%r11;		
	popq	%r10;		
	popq	%r9;		
	popq	%r8;		
	popq	%rbx;		
	popq	%rcx;		
	popq	%rdx;		
	popq	%rsi;		
	popq	%rdi;		
	popq	%rbp;		
	popq	%rax;		
	movq	%rax,	%ds;	
	popq	%rax;		
	movq	%rax,	%es;	
	popq	%rax;		
	addq	$0x10,	%rsp;

	iretq;

#define GET_CURRENT(reg)	\
	movq	$-32768,reg;	\
	andq	%rsp,	reg

ret_from_exception:
	/*GET_CURRENT(%ebx)	need rewrite*/
ENTRY(ret_from_intr)
	jmp	RESTORE_ALL	/*need rewrite*/
	







ENTRY(divide_error)
	xchg %bx,%bx
	pushq	$0
	pushq	%rax
	leaq	_ZN16interruptmanager15do_divide_errorEyy(%rip),	%rax
	xchgq	%rax,	(%rsp)

error_code:


	pushq	%rax
	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax
	xorq	%rax,	%rax

	pushq	%rbp
	pushq	%rdi
	pushq	%rsi
	pushq	%rdx
	pushq	%rcx
	pushq	%rbx
	pushq	%r8
	pushq	%r9
	pushq	%r10
	pushq	%r11
	pushq	%r12
	pushq	%r13
	pushq	%r14
	pushq	%r15	



	cld
	movq	ERRCODE(%rsp),	%rsi
	movq	FUNC(%rsp),	%rdx	

	movq	$0x10,	%rdi
	movq	%rdi,	%ds
	movq	%rdi,	%es

	movq	%rsp,	%rdi
	////GET_CURRENT(%ebx)

	callq 	*%rdx

	jmp	ret_from_exception	




//=======	ignore_int
ENTRY(ignore_int)

	cld
	pushq	%rax
	pushq	%rbx
	pushq	%rcx
	pushq	%rdx
	pushq	%rbp
	pushq	%rdi
	pushq	%rsi

	pushq	%r8
	pushq	%r9
	pushq	%r10
	pushq	%r11
	pushq	%r12
	pushq	%r13
	pushq	%r14
	pushq	%r15

	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax

	movq	$0x10,	%rax
	movq	%rax,	%ds
	movq	%rax,	%es


	movq 	%rsp, %rsi
	movq 	$0,   %rdi
	callq	_ZN16interruptmanager17DoInterruptHandleEyP10StackFrame
	movq	%rax, %rsp


	popq	%rax
	movq	%rax,	%ds
	popq	%rax
	movq	%rax,	%es

	popq	%r15
	popq	%r14
	popq	%r13
	popq	%r12
	popq	%r11
	popq	%r10
	popq	%r9
	popq	%r8

	popq	%rsi
	popq	%rdi
	popq	%rbp
	popq	%rdx
	popq	%rcx
	popq	%rbx
	popq	%rax

	iretq

ENTRY(debug)
	pushq	$0
	pushq	%rax
	leaq	do_debug(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(nmi)
	pushq	%rax
	cld;			
	pushq	%rax;	
	
	pushq	%rax
	movq	%es,	%rax
	pushq	%rax
	movq	%ds,	%rax
	pushq	%rax
	xorq	%rax,	%rax
	
	pushq	%rbp;		
	pushq	%rdi;		
	pushq	%rsi;		
	pushq	%rdx;		
	pushq	%rcx;		
	pushq	%rbx;		
	pushq	%r8;		
	pushq	%r9;		
	pushq	%r10;		
	pushq	%r11;		
	pushq	%r12;		
	pushq	%r13;		
	pushq	%r14;		
	pushq	%r15;
	
	movq	$0x10,	%rdx;	
	movq	%rdx,	%ds;	
	movq	%rdx,	%es;
	
	movq	$0,	%rsi
	movq	%rsp,	%rdi

	callq	do_nmi

	jmp	RESTORE_ALL

ENTRY(int3)
	pushq	$0
	pushq	%rax
	leaq	do_int3(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(overflow)
	pushq	$0
	pushq	%rax
	leaq	do_overflow(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(bounds)
	pushq	$0
	pushq	%rax
	leaq	do_bounds(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(undefined_opcode)
	pushq	$0
	pushq	%rax
	leaq	do_undefined_opcode(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(dev_not_available)	/* need rewrite */
	pushq	$0
	pushq	%rax
	leaq	do_dev_not_available(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code


ENTRY(double_fault)
	pushq	%rax
	leaq	do_double_fault(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(coprocessor_segment_overrun)
	pushq	$0
	pushq	%rax
	leaq	do_coprocessor_segment_overrun(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(invalid_TSS)
	pushq	%rax
	leaq	do_invalid_TSS(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(segment_not_present)
	pushq	%rax
	leaq	do_segment_not_present(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(stack_segment_fault)
	pushq	%rax
	leaq	do_stack_segment_fault(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(general_protection)
	xchg %bx,%bx
	pushq	%rax
	leaq	do_general_protection(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(page_fault)
	xchg %bx,%bx
	pushq	%rax
	leaq	do_page_fault(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(x87_FPU_error)
	pushq	$0
	pushq	%rax
	leaq	do_x87_FPU_error(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(alignment_check)
	pushq	%rax
	leaq	do_alignment_check(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(machine_check)
	pushq	$0
	pushq	%rax
	leaq	do_machine_check(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(SIMD_exception)
	pushq	$0
	pushq	%rax
	leaq	do_SIMD_exception(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code

ENTRY(virtualization_exception)
	pushq	$0
	pushq	%rax
	leaq	do_virtualization_exception(%rip),	%rax
	xchgq	%rax,	(%rsp)
	jmp	error_code



ENTRY(_stack_start)
	.quad (init_task_union + 32768 * 3 - 0x1000)


.data
interruptnumber:   .byte 0
